﻿//     Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http;
using Gateway.UpdateService.Manifests;
using Gateway.UpdateService.Models;
using Microsoft.Gateway.Utils;

namespace Gateway.UpdateService.Controllers
{
    public abstract class UpdateController : ApiController
    {
        string _containerUri;
        string _rootDirPath;

        protected UpdateController(string containerUrl, string rootDirPath)
        {
            _containerUri = containerUrl;
            _rootDirPath = rootDirPath;
        }

        // GET gateway
        public async Task<IEnumerable<PackageManifest>> Get()
        {
            return (await GetManifests()).Manifests;
        }

        // GET gateway/v0.6.2
        public async Task<PackageManifest> Get(string version)
        {
            PackageManifest manifest = null;
            if (String.Equals(version, "latest", StringComparison.OrdinalIgnoreCase))
            {
                // Special label to retrieve the most recent version
                manifest = (await GetManifests())
                    .Manifests
                    .LastOrDefault();
            }
            else
            {
                Version requestedVersion;
                try
                {
                    requestedVersion = VersionUtils.ParseVersion(version);
                }
                catch
                {
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
                }
                manifest = (await GetManifests(true))
                    .Manifest(requestedVersion);
            }
            if (manifest == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return manifest;
        }

        // GET gateway/?currentVersion=v0.6.2
        [HttpGet]
        public async Task<PackageManifest> GetManifestByMoreRecent(string currentVersion)
        {
            Version requestedVersion;
            try
            {
                requestedVersion = VersionUtils.ParseVersion(currentVersion);
            }
            catch
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }
            var updateManifest = (await GetManifests())
                .ManifestMoreRecent(requestedVersion);
            if (updateManifest == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return updateManifest;
        }

        // GET | HEAD gateway/v0.1.3/HTTP/ServiceConfiguration.Publish.cscfg
        [HttpHead]
        [HttpGet]
        public async Task<HttpResponseMessage> GetFileContents(string version, string package, string file)
        {
            return await GetFileContents(version, package, file, this.Request.Method == HttpMethod.Head, this.Request.Headers.Range);
        }

        /// <summary>
        /// Test hook
        /// </summary>
        public async Task<HttpResponseMessage> GetFileContents(string version, string package, string file, bool isHeadRequest, RangeHeaderValue requestBlobRange)
        {
            var versionManifest = await this.Get(version);
            return await BlobDownloader.BlobRequest(versionManifest, package, file, isHeadRequest, requestBlobRange);
        }

        async Task<StorageManifests> GetManifests(bool includeDisabled = false)
        {
            return await StorageManifests.CreateAsync(_containerUri, _rootDirPath, includeDisabled);

        }
    }
}